﻿module Sustainalytics.EsgRatings {

    export class EsgRpIndicatorsController {

        public indicatorClusters: EsgRpIndicatorClusterDto[];
        public selectedIndicatorCluster: EsgRpIndicatorClusterDto;

        public indicators: EsgRpIndicatorDto[] = [];
        public indicatorsSkip: number = 0;
        public indicatorsTake: number = 5;
        public lastGetData: any;
        public resetScrollPager: boolean = false;
        public scrollPagerLocked: boolean = true;


        constructor(
            private $scope: IEsgThemeScope,
            private $q: ng.IQService,
            private $timeout: ng.ITimeoutService,
            private EsgRpIndicatorClusterService: IEsgRpIndicatorClusterService,
            private EsgRpIndicatorService: IEsgRpIndicatorService,
            private $rootScope,
            private staticObjects: Common.IStaticObjects) {

            var ctx = this;

            $scope['esgRpIndicators'] = ctx;

            ctx.init();
        }


        private init(): ng.IPromise<any> {

            var ctx = this;

            var def = ctx.$q.defer();

            ctx.scrollPagerLocked = true;

            // get indicators clusters
            ctx.getIndicatorClusters().then(
                // success
                function () {

                    // get indicators for default cluster
                    ctx.getIndicators().then(
                        // success
                        function () {
                            ctx.scrollPagerLocked = false;
                            def.resolve();
                        },
                        // error
                        function () {
                            ctx.scrollPagerLocked = false;
                            def.reject();
                        });
                },
                // error
                function () {
                    def.reject();
                });


            // listen for scroll changes
            ctx.$scope.$watch('esgRpInd.indicatorsSkip', onPageChange);
            ctx.$scope.$watch('esgRpInd.indicatorsTake', onPageChange);

            // refresh on page changed
            function onPageChange() {
                ctx.getIndicators();
            };

            return def.promise;
        }

        private getIndicatorClusters(): ng.IPromise<any> {
            var ctx = this;

            var currentTheme = ctx.$scope.currentTheme;
            // get indicators clusters
            var indicatorClustersPromise = ctx.EsgRpIndicatorClusterService.get(currentTheme).then(
                // success
                function (indicatorClusters) {

                    // set indicator clusters
                    ctx.indicatorClusters = indicatorClusters;

                    // use first indicator as the default indicator cluster
                    if (ctx.indicatorClusters && ctx.indicatorClusters.length > 0) {
                        ctx.selectedIndicatorCluster = ctx.indicatorClusters[0];
                    }
                    else {
                        ctx.selectedIndicatorCluster = null;
                    }

                    ctx.$timeout(function () {
                        ctx.$scope.$apply();
                    });
                },() => {
                    ga('create', 'UA-4379897-6', {
                        'userId': ctx.$rootScope.userInfo.userId, 'cookieDomain': 'none', 'name': 'globalAccess'
                    });

                    ga('globalAccess.send', 'exception', { 'exDescription': 'Esg Ratings: Rp Indicators Controller -> Error loading Indicator Clusters' });
                });

            return indicatorClustersPromise;
        }

        private getIndicators(): ng.IPromise<any> {
            var ctx = this;

            if (!ctx.$scope.currentCompany || !ctx.$scope.currentTheme || !ctx.selectedIndicatorCluster) {
                return ctx.$q.when(null);
            }

            var getData =
                {
                    companyId: ctx.$scope.currentCompany.id,
                    clusterName: ctx.selectedIndicatorCluster.name,
                    theme: ctx.$scope.currentTheme,
                    skip: ctx.indicatorsSkip,
                    take: ctx.indicatorsTake
                };

            if (ctx.lastGetData && angular.equals(ctx.lastGetData, getData)) {
                return ctx.$q.when(null);
            }

            ctx.lastGetData = getData;

            var indicatorsPromise = ctx.EsgRpIndicatorService.get(
                getData.companyId,
                getData.clusterName,
                getData.theme,
                getData.skip,
                getData.take);


            indicatorsPromise.then(
                // success
                function (indicators) {

                    if (!indicators)
                            return;

                    // set indicators
                    ctx.indicators.push.apply(ctx.indicators, indicators);

                    // handle each indicator
                    $.each(ctx.indicators, function (index, ind) {

                        // associate a structure to each indicator so that all indicators values are grouped by indicator name and then ordered by year
                        ctx.groupNonRatedIndicatorsByName(ind);
                    });

                    ctx.$timeout(function () {
                        ctx.$scope.$apply();
                    });
                },() => {

                    ga('create', 'UA-4379897-6', {
                        'userId': ctx.$rootScope.userInfo.userId, 'cookieDomain': 'none', 'name': 'globalAccess'
                    });

                    ga('globalAccess.send', 'exception', { 'exDescription': 'Esg Ratings: Rp Indicators Controlle -> Error retrieving indicators' });
                });

            return indicatorsPromise;
        }

        private groupNonRatedIndicatorsByName(ind: EsgRpIndicatorDto) {
            var ctx = this;

            if (!ind || !ind.dataTable || ind.dataTable.length == 0)
                return;

            
            var minYear = 99999;
            var maxYear = 0;

            // get min and max year
            ind.dataTable.forEach(function (nonRatedInd) {
                if (nonRatedInd.year < minYear)
                    minYear = nonRatedInd.year;

                if (maxYear < nonRatedInd.year)
                    maxYear = nonRatedInd.year;
            });


            
            var nonRatedIndByName = new Common.Dictionary<Common.Dictionary<EsgRpNonRatedIndicatorValueDto>>();

            // non rated indicators values grouped by name and ordered by year
            ind.dataTable.forEach(function (nonRatedInd) {

                var nonRatedIndValues: Common.Dictionary<EsgRpNonRatedIndicatorValueDto>;

                if (nonRatedIndByName.containsKey(nonRatedInd.name)) {
                    nonRatedIndValues = nonRatedIndByName.getValue(nonRatedInd.name);
                }
                else {
                    nonRatedIndValues = new Common.Dictionary<EsgRpNonRatedIndicatorValueDto>();

                    // add dictionary of values ordered by year
                    nonRatedIndByName.add(nonRatedInd.name, nonRatedIndValues);

                    // add years to dictionary
                    for (var year = minYear; year <= maxYear; year++) {
                        nonRatedIndValues.add(year.toString(), { name: nonRatedInd.name, year: year, value: null });
                    }
                }

                // set indicator value
                var dicNonRatedInd = nonRatedIndValues.getValue(nonRatedInd.year.toString());
                $.extend(dicNonRatedInd, nonRatedInd, true);
            });


            // arrange dictionary into an array
            var nonRatedIndList = $.map(nonRatedIndByName.getItems(), function (nonRatedIndValues) {

                // create non rated indicator holding all its values
                var nonRatedInd = new EsgRpNonRatedIndicator(nonRatedIndValues.key, nonRatedIndValues.value.getValues().reverse());
                return nonRatedInd;
            });


            ind.dataTableByName = nonRatedIndList;

            // add non rated years
            ind.dataTableYears = [];
            for (var year = maxYear; year >= minYear; year--) {
                ind.dataTableYears.push(year);
            }
        }

        private selectIndicatorCluster(indicatorCluster: EsgRpIndicatorClusterDto) {
            var ctx = this;

            ctx.scrollPagerLocked = true;

            // remove items
            ctx.indicators = [];

            // set indicator cluster
            ctx.selectedIndicatorCluster = indicatorCluster;

            // reset paging
            ctx.resetScrollPager = true;
            ctx.indicatorsSkip = 0;

            // get indicator cluster indicators
            var indicatorsPromise = ctx.getIndicators();

            indicatorsPromise.then(function () {
                ctx.scrollPagerLocked = false;
            });

            ctx.$timeout(function () {
                ctx.$scope.$apply();
            });
        }
    }


    export var esgRpIndicatorsControllerName = 'EsgRpIndicatorsController';

    angular.module(esgRatingsModuleName).controller(esgRpIndicatorsControllerName, EsgRpIndicatorsController);
}